package com.wlsk.license.common.execl;


import cn.idev.excel.EasyExcel;
import cn.idev.excel.ExcelWriter;
import cn.idev.excel.write.metadata.WriteSheet;
import com.wlsk.license.common.exception.BusinessException;
import com.wlsk.license.common.utils.ValidationUtils;
import com.wlsk.license.dto.ExportDto;
import org.springframework.util.StopWatch;

import java.util.List;

/**
 * <p>@Description : Excel导出服务</p>
 * <p>@Author : Zhangbin.Liu </p>
 * <p>@Date : 2025/02/18 16:53 </p>
 */
public abstract class AbstractExcelExportService<DATA, PARAM> extends AbstractBaseExcelExportService<DATA, PARAM> {

    protected abstract List<DATA> data(PARAM param);

    /**
     * 返回下载地址
     *
     * @param param
     * @return
     */
    public final String export(PARAM param) {
        ExportDto exportDto = exportWithFileName(param);
        return exportDto.getUrl();
    }
    
    /**
     * 导出Excel并返回包含URL和文件名的对象
     *
     * @param param 导出参数
     * @return 包含URL和文件名的ExportDto对象
     */
    public ExportDto exportWithFileName(PARAM param) {
        // 只调用一次getName方法，将结果存储在变量中
        String name = getName(param);
        StopWatch stopWatch = new StopWatch("导出" + name);
        stopWatch.start();

        String path = getPath();
        String localFileName = getLocalFileName(param, path);
        try (ExcelWriter writer = EasyExcel.write(localFileName, this.getDataClass()).build()) {
            WriteSheet writeSheet = EasyExcel.writerSheet(name).build();
            List<DATA> data = data(param);
            ValidationUtils.notEmpty(data, "导出数据不能为空");
            ValidationUtils.isTrue(getLimit() <= 60000, "最多导出60000条记录");
            ValidationUtils.isTrue(data.size() <= getLimit() || getLimit() == 0, "共" + data.size() + "条记录，最多导出" + getLimit() + "条记录");
            writer.write(data, writeSheet);
        } catch (BusinessException e) {
            super.deleteLocalFile(localFileName);
            throw new BusinessException(e.getMessage());
        } catch (Exception e) {
            super.deleteLocalFile(localFileName);
            log.error("导出{}excel错误：{}", name, e.getMessage(), e);
            throw new BusinessException("导出" + name + "数据错误");
        }
        String downloadUrl = super.uploadOss(localFileName, name + ".xls");
        stopWatch.stop();
        log.info("导出{},耗时:{}秒................", localFileName, stopWatch.getTotalTimeSeconds());
        
        // 创建并返回ExportDto对象
        ExportDto exportDto = new ExportDto();
        exportDto.setFileName(name + ".xls");
        exportDto.setUrl(downloadUrl);
        return exportDto;
    }

    /**
     * 限制最多导出多少条数据，默认60000，为0不限制
     *
     * @return
     */
    @Override
    public long getLimit() {
        return 60000;
    }
}